package com.carl.dao;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;

import org.apache.commons.beanutils.PropertyUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.code.morphia.Datastore;
import com.google.code.morphia.dao.BasicDAO;
import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.UpdateOperations;

public class BasicDao<T> extends BasicDAO<T, ObjectId> {
	
	protected final Logger logger = LoggerFactory.getLogger(BasicDao.class);
	
	protected BasicDao(Datastore ds) {
		super(ds);
	}

	/**
     * 构造用户查询参数的 Query对象
     * @param userInfo
     * @param userQuery
     */
	protected Query<T> getEntityQuery(T entity) {
		
		@SuppressWarnings("unchecked")
		Query<T> entityQuery = (Query<T>) ds.find(entity.getClass());
		PropertyDescriptor[] arra = PropertyUtils.getPropertyDescriptors(entity.getClass());
		Object value = null;
		
		for (PropertyDescriptor propertyDescriptor : arra) {
			
			String name = propertyDescriptor.getName();			
			if("class".equals(name)){
				continue;
			}
			
			try {
				Object idValue = PropertyUtils.getProperty(entity, "id");
				if(idValue != null){
					entityQuery.filter("id =", idValue);
					break;
				}
				value = PropertyUtils.getProperty(entity, name);
			} catch (IllegalAccessException e) {
				logger.error("IllegalAccessException :", new Throwable(e));
			} catch (InvocationTargetException e) {
				logger.error("InvocationTargetException :", new Throwable(e));
			} catch (NoSuchMethodException e) {
				logger.error("NoSuchMethodException :", new Throwable(e));
			}
			if(value != null){
				entityQuery.filter(name + " =", value);
			}
		}
		return entityQuery;
	}
	
	/**
	 * 产生自己的UpdateOperations对象，并自动填充ops中的值
	 * @param userInfo
	 * @param ops
	 */
	protected UpdateOperations<T> getUpdateOperOfEntity(T entity) {
		
		@SuppressWarnings("unchecked")
		UpdateOperations<T> ops = (UpdateOperations<T>) ds.createUpdateOperations(entity.getClass());
		PropertyDescriptor[] arra = PropertyUtils.getPropertyDescriptors(entity.getClass());
		Object value = null;
		String name = null;
		
		for (PropertyDescriptor propertyDescriptor : arra) {
					
			name = propertyDescriptor.getName();			
			if("class".equals(name) || "id".equals(name)){
				continue;
			}
			try {
				value = PropertyUtils.getProperty(entity, name);
			} catch (IllegalAccessException e) {
				logger.error("IllegalAccessException :", new Throwable(e));
			} catch (InvocationTargetException e) {
				logger.error("InvocationTargetException :", new Throwable(e));
			} catch (NoSuchMethodException e) {
				logger.error("NoSuchMethodException :", new Throwable(e));
			}
			
			if(value != null){
				ops.set(name, value);
			}
		}
		
		return ops;
	}
}
